package aufgabe2_pop3;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.List;
import java.util.Scanner;

public class Server_Thread extends Thread {

	// Die Verbindung
	Socket connection = null;

	// Der Master
	Server_Administration_Control_I_for_Server_Thread control;
	Datenbank datenbank;

	//Laufwariablen
	boolean server_thread_authorization_in_progress;
	boolean server_run;
	
	/**
	 * @param connection Ein Socket Objekt fuer die Verbindung
	 * @param control Ein Control Objekt fuer die Verknuepung
	 * @param datenbank Ein Datenbank Objekt fuer die verfuegbarkeit der daten
	 */
	public Server_Thread(Socket connection, Server_Administration_Control_I_for_Server_Thread control, Datenbank datenbank) {
		this.connection = connection;
		this.control = control;
		this.datenbank = datenbank;
		
		server_run = true;
		server_thread_authorization_in_progress = true;
		
		setDaemon(false);
	}

	//Thread methode
	@Override
	public void run() {
		Scanner in;
		PrintWriter out;

		String user = null;
		String pass = null ;
		
		try{
		in = new Scanner(connection.getInputStream());
		out = new PrintWriter(connection.getOutputStream(), true);
		}catch (IOException e){
			control.server_thread_counter_down();
			datenbank.log("Server_Thread", "Server", "FEHLER BEI CONNECTIONAUFBAU");
			return;
		}
		
		datenbank.log("Server_Thread", "Server", "Verbindung aufgebaut");
		
		out.println(datenbank.log("Server_Thread", "Server Greting", "+OK Im here"));
		
		//Authorization
		while (!datenbank.login(user, pass)){
			if (in.hasNext()) {
				String input = datenbank.log("Server_Thread", "Client Auto",in.nextLine());
				String[] splitInput = input.split(" ", 2);
				if (splitInput.length == 2) {
					if (splitInput[0].equals("USER")) {
						user = splitInput[1]; out.println(datenbank.log("Server_Thread",  "Server USER", "+OK I have your Name"));
					} else if (splitInput[0].equals("PASS")) {
						pass = splitInput[1]; out.println(datenbank.log("Server_Thread", "Server PASS", datenbank.logintext(user, pass)));
					} else {
						out.println(datenbank.log("Server_Thread", "Server Befehl ERROR", "-ERR no valid command in authorization"));
					}
				} else {
					if (splitInput[0].equals("QUIT")) {
						out.println(datenbank.log("Server_Thread", "Server", "+OK POP3 server signing off")); 
						control.server_thread_counter_down();
						return;
					} else {
						out.println(datenbank.log("Server_Thread", "Server Befehl ERROR", "-ERR no valid command in authorization"));
					}
				}
			} else {
				my_sleep();
			}
		}
		
		//Transsmision
		while (server_run) {
			if (in.hasNext()) {
				String input = datenbank.log("Server_Thread", "Client Trans", in.nextLine());
				String[] splitInput = input.split(" ", 2);
				
				if (splitInput.length == 2) {
					if (splitInput[0].equals("LIST")) {
						out.println(datenbank.log("Server_Thread", "Server LIST", datenbank.list(new Integer(splitInput[1]))));
					} else if (splitInput[0].equals("RETR")) {
						multilineout(out, "Server RETR", datenbank.retr(new Integer(splitInput[1])));
					} else if (splitInput[0].equals("DELE")) {
						out.println(datenbank.log("Server_Thread", "Server DELE", datenbank.dele(new Integer(splitInput[1]))));
					} else if (splitInput[0].equals("UIDL")) {
						out.println(datenbank.log("Server_Thread", "Server UIDL", datenbank.uidl(new Integer(splitInput[1]))));
					} else {
						out.println(datenbank.log("Server_Thread", "Server Befehl ERROR", "-ERR no valid command in transaction"));
					}
				} else {
					if (splitInput[0].equals("STAT")) {
						out.println(datenbank.log("Server_Thread", "Server STAT", datenbank.stat()));
					} else if (splitInput[0].equals("LIST")) {
						multilineout(out, "Server LIST", datenbank.list());
					} else if (splitInput[0].equals("NOOP")) {
						out.println(datenbank.log("Server_Thread", "Server NOOP", "+OK"));
					} else if (splitInput[0].equals("RSET")) {
						out.println(datenbank.log("Server_Thread", "Server RSET", datenbank.rset()));
					} else if (splitInput[0].equals("UIDL")) {
						multilineout(out, "Server UIDL", datenbank.uidl());
					} else if (splitInput[0].equals("QUIT")) {
						out.println(datenbank.log("Server_Thread", "Server QUIT", datenbank.quit()));
						control.server_thread_counter_down();
						return;
					} else {
						out.println(datenbank.log("Server_Thread", "Server Befehl ERROR", "-ERR no valid command in transaction"));
					}
				}
			} else {
				my_sleep();
			}
		}
		
		in.close();
		out.close();
		control.server_thread_counter_down();
	}

	private void multilineout(PrintWriter out, String was, List<String> text){
		for(String line : text){
			out.println(datenbank.log("Server_Thread", was, line));
		}
	}

	public void my_sleep(){
		try {
			sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}
